package com.huawei.chengdu.meetingdemo.view;

import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Switch;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.device.idea.meeting.FlexibleLayout.model.FlexibleLayout;
import com.device.idea.meeting.FlexibleLayout.model.VideoLocalView;
import com.device.idea.meeting.FlexibleLayout.model.VideoRemoteView;
import com.device.idea.meeting.FlexibleLayout.model.VideoRemoteViewAndUser;
import com.device.idea.meeting.MultiStream.model.StreamType;
import com.device.idea.meeting.MultiStream.model.SurfaceViewInfo;
import com.huawei.chengdu.meetingdemo.R;
import com.huawei.chengdu.meetingdemo.presenter.ConfSdkPresenter;
import com.huawei.chengdu.meetingdemo.util.LogUtil;

import java.util.Collections;
import java.util.List;

public class InMeetingFragmentFlexible extends Fragment {
    private static final String TAG = InMeetingFragmentFlexible.class.getSimpleName();
    private View view;
    private SurfaceView surfaceViewLocal;
    private SurfaceView surfaceViewRemote;
    private SurfaceView surfaceViewRemoteAux;
    private SurfaceView surfaceViewLocalAux;
    private Button btnSendPreLocal;
    private Button btnSendPreRemote;
    private Button btnSendPreRemoteAux;
    private Button btnSendPreLocalAux;
    private Button btnCancelPreShow;
    private Switch switchShowLocal;
    private Switch switchShowRemote;
    private Switch switchShowRemoteAux;
    private Switch switchShowLocalAux;
    private MeetingPresentation mPresentation;
    private int displayId;
    private List<FlexibleLayout> flexibleLayoutInfoList;
    private StreamType curLocalAuxType;
    public static Handler mHandler;

    public InMeetingFragmentFlexible(List<FlexibleLayout> list) {
        super();
        flexibleLayoutInfoList = list;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_in_meeting_layout_flexible, container, false);
        mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                startShowView(StreamType.valueOf(msg.what));
            }
        };

        initView();
        initListener();
        handleFlexibleLayoutChangeNotify();
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        LogUtil.info(TAG + " onResume");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mPresentation != null) {
            mPresentation.stopShowView();
        }
    }

    private void initView() {
        surfaceViewLocal = view.findViewById(R.id.surface_Flexible_local);
        surfaceViewRemote = view.findViewById(R.id.surface_Flexible_remote);
        surfaceViewRemoteAux = view.findViewById(R.id.surface_Flexible_remote_aux);
        surfaceViewLocalAux = view.findViewById(R.id.surface_Flexible_local_aux);
        btnSendPreLocal = view.findViewById(R.id.send_presentation_local);
        btnSendPreRemote = view.findViewById(R.id.send_presentation_remote);
        btnSendPreRemoteAux = view.findViewById(R.id.send_presentation_remote_aux);
        btnSendPreLocalAux = view.findViewById(R.id.send_presentation_local_aux);
        btnCancelPreShow = view.findViewById(R.id.cancel_presentation_show);
        switchShowLocal = view.findViewById(R.id.switch_show_local);
        switchShowRemote = view.findViewById(R.id.switch_show_remote);
        switchShowRemoteAux = view.findViewById(R.id.switch_show_remote_aux);
        switchShowLocalAux = view.findViewById(R.id.switch_show_local_aux);
    }

    private void initListener() {
        btnSendPreLocal.setOnClickListener((v -> sendLocalToPre()));
        btnSendPreRemote.setOnClickListener(v -> sendRemoteToPre());
        btnSendPreRemoteAux.setOnClickListener(v -> sendRemoteAuxToPre());
        btnSendPreLocalAux.setOnClickListener(v -> sendLocalAuxToPre());
        btnCancelPreShow.setOnClickListener(v -> cancelPreShow());
        switchShowLocal.setOnCheckedChangeListener((buttonView, isChecked) ->
                switchShowListener(StreamType.STREAM_LOCAL_MAIN, isChecked));
        switchShowRemote.setOnCheckedChangeListener((buttonView, isChecked) ->
                switchShowListener(StreamType.STREAM_REMOTE_MAIN, isChecked));
        switchShowRemoteAux.setOnCheckedChangeListener((buttonView, isChecked) ->
                switchShowListener(StreamType.STREAM_REMOTE_AUX, isChecked));
        switchShowLocalAux.setOnCheckedChangeListener((buttonView, isChecked) ->
                switchShowListener(curLocalAuxType != null ? curLocalAuxType : StreamType.STREAM_LOCAL_AUX, isChecked));
    }

    private void switchShowListener(StreamType streamType, boolean isChecked) {
        if (isChecked) {
            startShowView(streamType);
        } else {
            stopShowView(streamType);
        }
    }

    /**
     * 取消辅屏显示
     */
    private void cancelPreShow() {
        if (mPresentation == null || mPresentation.currentShowType == null) {
            return;
        }
        startShowView(mPresentation.currentShowType);
        mPresentation.stopShowView();
    }

    private void startShowView(StreamType streamType) {
        switch (streamType) {
            case STREAM_LOCAL_MAIN:
                surfaceViewLocal.setVisibility(View.VISIBLE);
                startLocalView(streamType, 0, surfaceViewLocal);
                break;
            case STREAM_REMOTE_MAIN:  // 单流会议的userId为-1，多流会议应该从onFlexibleLayoutNotify的回调中获取对应布局的userId
                surfaceViewRemote.setVisibility(View.VISIBLE);
                startRemoteView(-1, streamType, 0, surfaceViewRemote);
                break;
            case STREAM_REMOTE_AUX:
                surfaceViewRemoteAux.setVisibility(View.VISIBLE);
                startRemoteView(-1, streamType, 0, surfaceViewRemoteAux);
                break;
            case STREAM_WIRELESS_PROJECTION:
            case STREAM_WIRED_PROJECTION:
                curLocalAuxType = streamType;
                surfaceViewLocalAux.setVisibility(View.VISIBLE);
                startLocalView(streamType, 0, surfaceViewLocalAux);
                break;
        }
    }

    private void stopShowView(StreamType streamType) {
        switch (streamType) {
            case STREAM_LOCAL_MAIN:
                surfaceViewLocal.setVisibility(View.GONE);
                ConfSdkPresenter.stopLocalView(streamType);
                break;
            case STREAM_REMOTE_MAIN:
                surfaceViewRemote.setVisibility(View.GONE);
                ConfSdkPresenter.stopRemoteView(-1, streamType);
                break;
            case STREAM_REMOTE_AUX:
                surfaceViewRemoteAux.setVisibility(View.GONE);
                ConfSdkPresenter.stopRemoteView(-1, streamType);
                break;
            case STREAM_WIRELESS_PROJECTION:
            case STREAM_WIRED_PROJECTION:
                surfaceViewLocalAux.setVisibility(View.GONE);
                ConfSdkPresenter.stopLocalView(streamType);
                break;
        }
    }

    /**
     * 将视频流发送辅屏显示
     */
    private void sendLocalToPre() {
        initPresentation();
        if (mPresentation != null) {
            mPresentation.startShowView(StreamType.STREAM_LOCAL_MAIN);
            startLocalView(StreamType.STREAM_LOCAL_MAIN, displayId, mPresentation.surfacePresentation);
            surfaceViewLocal.setVisibility(View.GONE);
        }
    }

    private void sendRemoteToPre() {
        initPresentation();
        if (mPresentation != null) {
            mPresentation.startShowView(StreamType.STREAM_REMOTE_MAIN);
            startLocalView(StreamType.STREAM_REMOTE_MAIN, displayId, mPresentation.surfacePresentation);
            surfaceViewRemote.setVisibility(View.GONE);
        }
    }

    private void sendLocalAuxToPre() {
        initPresentation();
        if (mPresentation != null) {
            mPresentation.startShowView(curLocalAuxType);
            startLocalView(curLocalAuxType, displayId, mPresentation.surfacePresentation);
            surfaceViewLocalAux.setVisibility(View.GONE);
        }
    }

    private void sendRemoteAuxToPre() {
        initPresentation();
        if (mPresentation != null) {
            mPresentation.startShowView(StreamType.STREAM_REMOTE_MAIN);
            startLocalView(StreamType.STREAM_REMOTE_MAIN, displayId, mPresentation.surfacePresentation);
            surfaceViewRemoteAux.setVisibility(View.GONE);
        }
    }

    private void initPresentation() {
        if (mPresentation != null) return;
        DisplayManager displayManager = (DisplayManager) getActivity().getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
        if (displays.length == 0) {
            Toast.makeText(getContext(), "未检测到辅屏接入", Toast.LENGTH_LONG).show();
            return;
        }
        displayId = displays[0].getDisplayId();
        mPresentation = new MeetingPresentation(getContext(), displays[0]);
        mPresentation.show();
    }

    public void handleFlexibleLayoutChangeNotify() {
        for (FlexibleLayout flexibleLayout : flexibleLayoutInfoList) {
            startShowView(StreamType.valueOf(flexibleLayout.getStreamType()));
        }
    }

    public void setFlexibleLayout(List<FlexibleLayout> list) {
        flexibleLayoutInfoList.clear();
        flexibleLayoutInfoList.addAll(list);
    }

    private void startLocalView(StreamType streamType, int displayId, SurfaceView surfaceView) {
        surfaceView.post(() -> {
            VideoLocalView localView = new VideoLocalView();
            localView.setStreamType(streamType.getVal());
            localView.setDisplayId(displayId);
            SurfaceViewInfo surfaceViewInfo = new SurfaceViewInfo();
            surfaceViewInfo.setSurfaceView(surfaceView);
            localView.setView(surfaceViewInfo);
            ConfSdkPresenter.startLocalView(localView);
        });
    }

    private void startRemoteView(int userId, StreamType streamType, int displayId, SurfaceView surfaceView) {
        surfaceView.post(() -> {
            VideoRemoteViewAndUser user = new VideoRemoteViewAndUser();
            user.setUserId(userId);
            VideoRemoteView remoteView = new VideoRemoteView();
            remoteView.setStreamType(streamType.getVal());
            remoteView.setDisplayId(displayId);
            SurfaceViewInfo surfaceViewInfo = new SurfaceViewInfo();
            surfaceViewInfo.setSurfaceView(surfaceView);
            remoteView.setView(surfaceViewInfo);
            user.setVideoRemoteView(remoteView);
            ConfSdkPresenter.startRemoteView(Collections.singletonList(user));
        });
    }

}
